package spring.cloud.tasks.tasks_manager.schedule;

import spring.cloud.tasks.common.curator.Curator;
import spring.cloud.tasks.common.nodepaths.TaskBaseInfoNode;
import spring.cloud.tasks.common.nodepaths.TaskNodePaths;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 进行任务时间点的生成+实例信息生成+管理,必须配置信息存在。
 */
public class TaskConfigurationManager {
    public final ConcurrentHashMap<String, TaskConfiguration> taskIdToTaskConfigurationMap = new ConcurrentHashMap<>();
    private final ScheduleManager scheduleManager;
    private final AtomicBoolean inited = new AtomicBoolean(false);
    public ConcurrentHashMap<String, ExecutableDateTimePointBaseInfo> taskIdToExecutableDateTimePointBaseInfoMap = new ConcurrentHashMap<>();

    public TaskConfigurationManager(ScheduleManager scheduleManager) {
        this.scheduleManager = scheduleManager;
    }

    /**
     * 在刷新过程中需要对任务的版本号进行比较。
     */
    public void refresh() throws Exception {
        if (!inited.get()) {
            inited.set(true);
        }
        String tasksNodePath = TaskNodePaths.getROOT();
        Curator curator = scheduleManager.curator;
        List<String> newTaskIdList = curator.getChildren(tasksNodePath);
        if (newTaskIdList == null) {
            return;
        }
        Set<String> oldTaskIdList = taskIdToTaskConfigurationMap.keySet();//old缺少的直接去掉6分钟之前没有的任务信息。
        //新保证新的配置信息加载
        for (String newTaskId : newTaskIdList) {
            if (oldTaskIdList.contains(newTaskId)) {
                //比较版本 如果和本地的版本一致则不进行更新
                long taskVersion = getVersionFromZk(newTaskId);
                TaskConfiguration taskConfiguration = taskIdToTaskConfigurationMap.get(newTaskId);
                //获取最新版本的数据
                if (taskConfiguration == null || taskConfiguration.getTaskDto().getUpdateVersion() < taskVersion) {
                    taskConfiguration = getTaskConfigurationFromZk(newTaskId);
                    if (taskConfiguration != null) {
                        taskConfiguration.setTaskVersion(taskVersion);
                        taskIdToTaskConfigurationMap.put(newTaskId, taskConfiguration);
                    }

                }
            } else {
                long taskVersion = getVersionFromZk(newTaskId);
                TaskConfiguration taskConfiguration = getTaskConfigurationFromZk(newTaskId);
                if (taskConfiguration != null) {
                    taskConfiguration.setTaskVersion(taskVersion);
                    taskIdToTaskConfigurationMap.put(newTaskId, taskConfiguration);
                }
            }
        }
        for (String oldTaskId : oldTaskIdList) {
            if (!newTaskIdList.contains(oldTaskId)) {
                TaskConfiguration taskConfiguration = taskIdToTaskConfigurationMap.get(oldTaskId);
                if (taskConfiguration != null) {
                    long version = taskConfiguration.getTaskDto().getUpdateVersion();
                    if (version < System.currentTimeMillis() - 1000L * 60 * 30) {//创建执行点是24分钟,30分钟来保证任务信息不会为空的情况出现。如果针对为空，那么立即获取。
                        taskIdToTaskConfigurationMap.remove(oldTaskId);
                    }
                }
            }
        }

    }


    private long getVersionFromZk(String newTaskId) throws Exception {
        String taskVersionNodePath = TaskNodePaths.getTaskNodePath(newTaskId);
        Curator curator = scheduleManager.curator;
        return Long.parseLong(curator.getData(taskVersionNodePath));
    }

    TaskConfiguration getTaskConfigurationFromZk(String newTaskId) throws Exception {
        String taskVersionNodePath = TaskNodePaths.getTaskNodePath(newTaskId, TaskBaseInfoNode.baseInfoNode);
        Curator curator = scheduleManager.curator;
        String data = curator.getData(taskVersionNodePath);
        TaskConfiguration taskConfiguration = new TaskConfiguration(newTaskId);
        return taskConfiguration;
    }

    /**
     * 假定任务的配置信息一定存在。
     *
     * @param newTaskId
     * @return
     * @throws Exception
     */
    public TaskConfiguration getTaskConfiguration(String newTaskId) throws Exception {
        TaskConfiguration taskConfiguration = taskIdToTaskConfigurationMap.get(newTaskId);
        if (taskConfiguration == null) {
            taskConfiguration = getTaskConfigurationFromZk(newTaskId);
            taskIdToTaskConfigurationMap.put(newTaskId, taskConfiguration);
            return taskConfiguration;
        } else {
            return taskConfiguration;
        }
    }

    public List<String> getTaskIdList() {
        Set<String> oldTaskIdList = taskIdToTaskConfigurationMap.keySet();//old缺少的直接去掉6分钟之前没有的任务信息。
        List<String> taskIdList = new ArrayList<>();
        for (String oldTaskId : oldTaskIdList) {
            boolean containsKey = taskIdToTaskConfigurationMap.containsKey(oldTaskId);
            if (containsKey) {
                taskIdList.add(oldTaskId);
            }
        }
        return taskIdList;
    }

}
